package com.game.centerserver.controller;


import cn.dev33.satoken.stp.StpUtil;
import com.game.centerserver.common.Result;
import com.game.centerserver.infrastructure.entity.*;
import com.game.centerserver.infrastructure.service.ArchiveService;
import com.game.centerserver.infrastructure.service.DstClusterIniService;
import com.game.centerserver.infrastructure.service.DstClusterTokenService;
import com.game.centerserver.infrastructure.service.DstServerIniService;
import com.game.centerserver.service.GenerateArchive;
import com.game.centerserver.service.OrderServiceService;
import com.game.centerserver.service.UserServiceService;
import com.game.centerserver.view.ArchiveView;
import com.game.centerserver.view.ClusterIniView;
import jakarta.annotation.Resource;
import lombok.val;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * (Archive)表控制层
 *
 * @author makejava
 * @since 2024-11-13 21:49:32
 */
@RestController
@RequestMapping("/archive")
public class ArchiveController {
    /**
     * 存档服务对象
     */
    @Resource
    private ArchiveService archiveService;

    @Resource
    private DstClusterIniService dstClusterIniService;

    @Resource
    private DstServerIniService dstServerIniService;

    @Resource
    private DstClusterTokenService dstClusterTokenService;

    @Resource
    private GenerateArchive generateArchive;

    @Resource
    private UserServiceService userServiceService;

    @Resource
    private OrderServiceService orderServiceService;

    /**
     * 添加存档的相关配置信息和存档信息
     * @param archiveView
     * @return
     */
    @Transactional
    @PostMapping("/addArchiveConfig")
    public Result<ArchiveView> addArchiveConfig(@RequestBody ArchiveView archiveView){
        //创建目录
        String uid = StpUtil.getLoginIdAsString();
        String archiveId = "dst@"+System.currentTimeMillis();

        if (archiveView == null || archiveView.getClusterIniView() == null) {
            return Result.fail("世界配置参数为空");
        }

        //添加cluster.ini配置
        ClusterIniView clusterIniView = archiveView.getClusterIniView();
        DstClusterIni dstClusterIni = new DstClusterIni();
        dstClusterIni.setArchiveId(archiveId);
        if(!clusterIniView.getGameMode().equals("survival") &&
            !clusterIniView.getGameMode().equals("endless") &&
            !clusterIniView.getGameMode().equals("wilderness")){
            return Result.fail("只支持survival, endless, wilderness三种模式");
        }
        dstClusterIni.setGameMode(clusterIniView.getGameMode());
        dstClusterIni.setMaxPlayers(clusterIniView.getMaxPlayers());
        dstClusterIni.setPvp(clusterIniView.getPvp());
        dstClusterIni.setClusterName(clusterIniView.getClusterName());
        dstClusterIni.setClusterDescription(clusterIniView.getClusterDescription());
        dstClusterIni.setClusterPassword(clusterIniView.getClusterPassword());
        dstClusterIni.setPauseWhenEmpty(1);
        dstClusterIni.setConsoleEnabled(1);
        dstClusterIni.setShardEnabled(1);
        dstClusterIni.setClusterKey("supersecretkey");

        boolean insertDstClusterIni = dstClusterIniService.insert(dstClusterIni);
        if(!insertDstClusterIni){
            return Result.fail("dstClusterIni添加失败");
        }

        // TODO 持久化世界配置   （后续完成）

        //添加Master的server.ini配置
        DstServerIni dstMasterServerIni = new DstServerIni();
        dstMasterServerIni.setIsMaster(1);
        dstMasterServerIni.setArchiveId(archiveId);
        dstMasterServerIni.setEncodeUserPathBool(true);
        boolean insertDstMasterServerIni = dstServerIniService.insert(dstMasterServerIni);
        if(!insertDstMasterServerIni){
            return Result.fail("dstServerIni添加失败");
        }

        //添加Caves的server.ini配置
        DstServerIni dstCavesServerIni = new DstServerIni();
        dstCavesServerIni.setArchiveId(archiveId);
        dstCavesServerIni.setIsMaster(0);
        dstCavesServerIni.setName("Caves");
        boolean insertDstCavesServerIni = dstServerIniService.insert(dstCavesServerIni);
        if(!insertDstCavesServerIni){
            return Result.fail("dstServerIni添加失败");
        }

        String archivePath = generateArchive.generateArchiveDirection(uid, archiveId);
        if (archivePath == null ) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("添加失败");
        }
        Archive archive = new Archive();
        archive.setArchiveId(archiveId);
        archive.setRemote(0);
        archive.setLocalPath(archivePath);
        archive.setUid(uid);
        boolean insertArchive = archiveService.insert(archive);
        if (!insertArchive){
            return Result.fail("添加存档信息失败");
        }

        archiveView.setArchiveId(archiveId);
        return Result.ok("成功持久化存档配置并生成存档文件",archiveView);
    }

    /**
     * 根据archiveId生成完整的存档
     * @param map
     * @return
     */
    @PostMapping("/generateCompleteArchiveFile")
    public Result generateCompleteArchiveFile(@RequestBody Map<String,Object> map){
        Result result = generateArchive.generateCompleteArchive((String) map.get("archiveId"),(List<String>)map.get("modList"));
        return result;
    }

    /**
     * 通过archiveId查询存档信息
     *
     * @param archiveId 主键
     * @return 单条数据
     */
    @GetMapping("/queryById")
    public Result queryById(String archiveId) {
        Archive archive = archiveService.queryById(archiveId);
        return Result.ok("获取成功",archive);
    }

    /**
     * 修改存档配置信息(只修改了dstClusterIni信息和世界配置信息以及mod信息)
     * @param archiveView 实体
     * @return 编辑结果
     */
    @PutMapping("/updateArchiveConfig")
    public Result updateArchiveConfig(ArchiveView archiveView) {
        //添加cluster.ini配置
        ClusterIniView clusterIniView = archiveView.getClusterIniView();
        DstClusterIni dstClusterIni = new DstClusterIni();
        dstClusterIni.setArchiveId(archiveView.getArchiveId());
        dstClusterIni.setGameMode(clusterIniView.getGameMode());
        dstClusterIni.setMaxPlayers(clusterIniView.getMaxPlayers());
        dstClusterIni.setPvp(clusterIniView.getPvp());
        dstClusterIni.setClusterName(clusterIniView.getClusterName());
        dstClusterIni.setClusterDescription(clusterIniView.getClusterDescription());
        dstClusterIni.setClusterPassword(clusterIniView.getClusterPassword());
        boolean updateClusterIniResult = dstClusterIniService.update(dstClusterIni);
        if (!updateClusterIniResult){
            return Result.fail("修改dstClusterIni信息失败");
        }

        // TODO 修改世界配置

        return Result.ok("修改存档配置信息成功");
    }

    /**
     * 修改DstServerIni信息
     * @param dstServerIni
     * @return
     */
    @PutMapping("/updateDstServerIni")
    public Result updateDstServerIni(DstServerIni dstServerIni){
        boolean update = dstServerIniService.update(dstServerIni);
        if (!update){
            return Result.fail("修改DstServerIni信息失败");
        }
        return Result.ok("修改DstServerIni信息成功");
    }

    /**
     * 修改DstClusterToken信息
     * @param dstClusterToken
     * @return
     */
    @PutMapping("/updateDstClusterToken")
    public Result updateDstClusterToken(DstClusterToken dstClusterToken){
        boolean update = dstClusterTokenService.update(dstClusterToken);
        if (!update){
            return Result.fail("修改DstClusterToken信息失败");
        }
        return Result.ok("修改DstClusterToken信息成功");
    }

    /**
     * 修改存档信息
     * @param archive 实体
     * @return 编辑结果
     */
    @PutMapping("/updateArchive")
    public Result updateArchive(Archive archive) {
        boolean update = archiveService.update(archive);
        if (update){
            return Result.ok("修改成功");
        }else {
            return Result.fail("修改失败");
        }
    }

    /**
     * 根据archiveId获取存档配置信息
     * @param archiveId
     * @return
     */
    @GetMapping("/queryArchiveConfigByArchiveId")
    public Result queryArchiveConfigByArchiveId(String archiveId){
        ArchiveView archiveView = null;
        try {
            //获取cluster.ini信息
            DstClusterIni dstClusterIni = dstClusterIniService.queryByArchiveId(archiveId);
            ClusterIniView clusterIniView = new ClusterIniView();
            clusterIniView.setMaxPlayers(dstClusterIni.getMaxPlayers());
            clusterIniView.setGameMode(dstClusterIni.getGameMode());
            clusterIniView.setPvp(dstClusterIni.getPvp().equals("true") ? 1 : 0);
            clusterIniView.setClusterName(clusterIniView.getClusterName());
            clusterIniView.setClusterPassword(clusterIniView.getClusterPassword());
            clusterIniView.setClusterDescription(clusterIniView.getClusterDescription());

            archiveView = new ArchiveView();
            archiveView.setArchiveId(archiveId);
            archiveView.setClusterIniView(clusterIniView);
            // TODO archiveView.setWorldSetting();
            // TODO archiveView.setModIdList();
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("根据archiveId获取存档配置信息失败");
        }
        return Result.ok("根据archiveId获取存档配置信息成功",archiveView);
    }

    /**
     * 根据用户uid查询该用户的所有存档配置信息
     * @param uid
     * @return
     */
    @GetMapping("/queryArchiveConfigByUid")
    public Result queryArchiveConfigByUid(String uid){
        HashMap<String, ArchiveView> map = null;
        try {
            User user = userServiceService.queryUserByUid(uid);
            String archiveIdListString = user.getArchiveId();
            String[] archiveIdList = archiveIdListString.split(",");
            map = new HashMap<>();
            for (String archiveId : archiveIdList) {
                Result result = queryArchiveConfigByArchiveId(archiveId);
                if (result.getData() != null){
                    map.put(archiveId,(ArchiveView) result.getData());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("获取用户所有存档配置信息失败");
        }

        return Result.ok("获取用户所有存档配置信息成功",map);
    }

    /**
     * 删除数据
     *
     * @param archiveId 主键
     * @return 删除是否成功
     */
    @DeleteMapping("/deleteArchiveById")
    @Transactional
    public Result deleteById(String archiveId) {
        boolean deleteArchive = archiveService.deleteById(archiveId);
        boolean deleteClusterIni = dstClusterIniService.deleteByArchiveId(archiveId);
        boolean deleteClusterToken = false;
        DstClusterToken dstClusterToken = dstClusterTokenService.queryByArchiveId(archiveId);
        if (dstClusterToken != null) {
            dstClusterToken.setArchiveId(null);
            deleteClusterToken = dstClusterTokenService.update(dstClusterToken);
        }
        boolean deleteServerIni = dstServerIniService.deleteArchiveId(archiveId);
        if (deleteArchive && deleteClusterIni && deleteClusterToken && deleteServerIni){
            return Result.ok("删除成功");
        }else{
            return Result.fail("删除失败");
        }
    }

}

